/**
 * Title :	jFamilyTree generator
 * Description: jFamilyTree generator
 * Version:	provider
 * Copyright (c) 2001-2008
 * Terms of use:see license agreement at http://treebolic.sourceforge.net/en/license.htm
 * Author: Bernard Bou
 * Company: bsys
 */
package jFamilyTree.generator;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.WindowEvent;

import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.tree.TreeCellRenderer;

import jFamilyTree.IContext;
import jFamilyTree.IWidget;
import jFamilyTree.Messages;
import jFamilyTree.Widget;
import jFamilyTree.generator.domtree.DomTreeView;
import jFamilyTree.generator.tree.TreeView;

/**
 * Main frame
 * 
 * @author Bernard Bou
 */
/**
 * @author bbou
 */
/**
 * @author bbou
 */
public class MainFrame extends JFrame
{
	private static final long serialVersionUID = 1L;

	/**
	 * Tree icon
	 */
	static Icon theTreeIcon = new ImageIcon(MainFrame.class.getResource("images/treetab.png")); //$NON-NLS-1$

	/**
	 * Tree icon
	 */
	static Icon thejFamilyTreeIcon = new ImageIcon(MainFrame.class.getResource("images/jFamilyTreetab.png")); //$NON-NLS-1$

	/**
	 * Rendering mode
	 */
	static public final boolean hasjFamilyTreeRendering = true;

	/**
	 * Property view
	 */
	private PropertyView thePropertyView;

	/**
	 * jFamilyTree widget
	 */
	private IWidget theWidget;

	/**
	 * Controller
	 */
	private Controller theController;

	/**
	 * Tree view
	 */
	private TreeView theTreeView;

	/**
	 * Dom tree view
	 */
	private DomTreeView theDomTreeView;

	/**
	 * Text view
	 */
	private TextView theTextView;

	/**
	 * Tabbed pane
	 */
	private JTabbedPane theTabbedPane;

	/**
	 * Toolbar panel
	 */
	private JPanel theToolbarPanel;

	// C O N S T R U C T O R

	/**
	 * Constructor
	 */
	public MainFrame(String[] theseArgs)
	{
		super();
		theController = new Controller(theseArgs);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		initialize();

		// pack frame with preferred size data
		pack();

		// show frame
		setVisible(true);

		// open
		String thisDocumentPath = theController.getParameter("doc"); //$NON-NLS-1$
		if (thisDocumentPath != null && !thisDocumentPath.isEmpty())
			theController.open(thisDocumentPath);
	}

	/**
	 * Make mainframe
	 */
	private void initialize()
	{
		theWidget = makeWidget(theController);
		theTreeView = makeTreeView(theController);
		thePropertyView = makePropertyView(theController);
		theTextView = makeTextView();
		theDomTreeView = makeDomTreeView();
		theToolbarPanel = makeToolbarPanel(theController);

		JPanel thisContentPane = new JPanel();
		thisContentPane.setLayout(new BorderLayout());
		thisContentPane.add(makeTabbedPane(theController), BorderLayout.CENTER);
		thisContentPane.add(theToolbarPanel, BorderLayout.EAST);

		setJMenuBar(makeMenubar(theController));
		setContentPane(thisContentPane);
		setTitle(Messages.getString("MainFrame.0")); //$NON-NLS-1$

		// connect controller
		theController.connect(theWidget);
		theController.connect(thePropertyView);
		theController.connect(theTreeView);
		theController.connect(theTextView);
		theController.connect(theDomTreeView);
		theController.connect(theTabbedPane);
		theController.connect(this);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.Window#processWindowEvent(java.awt.event.WindowEvent)
	 */
	protected void processWindowEvent(WindowEvent thisEvent)
	{
		if (thisEvent.getID() == WindowEvent.WINDOW_CLOSING)
			theController.exit();
		super.processWindowEvent(thisEvent);
	}

	// C O M P O N E N T S

	/**
	 * Make the menu bar
	 * 
	 * @return javax.swing.JMenuBar
	 */
	private Menubar makeMenubar(final Controller thisController)
	{
		Menubar thisMenubar = new Menubar();
		thisMenubar.setController(thisController);
		return thisMenubar;
	}

	/**
	 * Make the toolbar space
	 * 
	 * @return javax.swing.JToolBar
	 */
	private JPanel makeToolbarPanel(final Controller thisController)
	{
		JPanel thisToolbarPanel = new JPanel();
		thisToolbarPanel.setLayout(new BoxLayout(thisToolbarPanel, BoxLayout.Y_AXIS));
		thisToolbarPanel.add(makeToolbar(thisController));
		thisToolbarPanel.add(makeTreeToolbar(thisController));
		return thisToolbarPanel;
	}

	/**
	 * Make the toolbar
	 * 
	 * @return javax.swing.JToolBar
	 */
	private Toolbar makeToolbar(final Controller thisController)
	{
		Toolbar thisToolBar = new Toolbar();
		thisToolBar.setController(thisController);
		return thisToolBar;
	}

	/**
	 * Make the toolbar
	 * 
	 * @return javax.swing.JToolBar
	 */
	private TreeToolbar makeTreeToolbar(final Controller thisController)
	{
		TreeToolbar thisToolBar = new TreeToolbar();
		thisToolBar.setController(thisController);
		return thisToolBar;
	}

	/**
	 * Make the tabbed pane
	 * 
	 * @return javax.swing.JTabbedPane
	 */
	private JTabbedPane makeTabbedPane(final Controller thisController)
	{
		theTabbedPane = new JTabbedPane();
		makeTab(theTabbedPane, Messages.getString("MainFrame.10"), theTreeIcon, makeEditor(thisController), new Runnable() //$NON-NLS-1$
		{
			public void run()
			{
				theController.updateTree();
			}
		});
		makeTab(theTabbedPane, Messages.getString("MainFrame.20"), thejFamilyTreeIcon, makeView(thisController), new Runnable() //$NON-NLS-1$
		{
			public void run()
			{
				theController.updateWidget();
			}
		});
		makeTab(theTabbedPane, Messages.getString("MainFrame.30"), null, new JScrollPane(theDomTreeView), new Runnable() //$NON-NLS-1$
		{
			public void run()
			{
				theController.updateDom();
			}
		});
		makeTab(theTabbedPane, Messages.getString("MainFrame.40"), null, new JScrollPane(theTextView), new Runnable() //$NON-NLS-1$
		{
			public void run()
			{
				theController.updateText();
			}
		});
		theTabbedPane.addChangeListener(thisController);
		theTabbedPane.addChangeListener(new ChangeListener()
		{
			public void stateChanged(ChangeEvent thisEvent)
			{
				int thisSelectedTabIndex = theTabbedPane.getSelectedIndex();
				theToolbarPanel.getComponent(1).setVisible(thisSelectedTabIndex == 0);
			}
		});
		return theTabbedPane;
	}

	/**
	 * Make tab
	 * 
	 * @param thisTabbedPane
	 *        tabbed pane
	 * @param thisTitle
	 *        title
	 * @param thisIcon
	 *        tab icon
	 * @param thisComponent
	 *        component
	 * @param thisAction
	 *        component update runnable
	 */
	private void makeTab(JTabbedPane thisTabbedPane, String thisTitle, Icon thisIcon, Component thisComponent, Runnable thisAction)
	{
		thisTabbedPane.addTab(thisTitle, thisIcon, thisComponent, null);
		theController.theUpdateMap.put(thisComponent, thisAction);
	}

	/**
	 * Make the html view
	 * 
	 * @return javax.swing.JPanel
	 */
	private TreeView makeTreeView(final Controller thisController)
	{
		TreeView thisTreeView = new TreeView();
		thisTreeView.connect(thisController);
		thisTreeView.setPreferredSize(new Dimension(400, 500));
		return thisTreeView;
	}

	/**
	 * Make the jFamilyTree view
	 * 
	 * @return jFamilyTree view
	 */
	private JPanel makeView(final Controller thisController)
	{
		JPanel thisView = new JPanel();
		thisView.setLayout(new BorderLayout());
		thisView.add((Component) theWidget, BorderLayout.CENTER);
		return thisView;
	}

	/**
	 * Make the widget
	 * 
	 * @return widget
	 */
	private Widget makeWidget(final IContext thisContext)
	{
		Widget thisWidget = new Widget(thisContext);
		return thisWidget;
	}

	/**
	 * Make the text view
	 * 
	 * @return text view
	 */
	private TextView makeTextView()
	{
		TextView thisTextView = new TextView();
		return thisTextView;
	}

	/**
	 * Make the property view
	 * 
	 * @return property view
	 */
	private PropertyView makePropertyView(final Controller thisController)
	{
		PropertyView thisPropertyView = new PropertyView();
		thisPropertyView.setImageRepository(thisController.makeImageRepositoryURL());
		thisPropertyView.setCellEditorListener(thisController);
		return thisPropertyView;
	}

	/**
	 * Make the Dom tree view
	 * 
	 * @return Dom tree view
	 */
	private DomTreeView makeDomTreeView()
	{
		TreeCellRenderer thisRenderer = hasjFamilyTreeRendering ? new jFamilyTree.generator.domtree.treebolic.Renderer() : new jFamilyTree.generator.domtree.Renderer();
		DomTreeView thisDomTreeView = new DomTreeView(thisRenderer);
		return thisDomTreeView;
	}

	/**
	 * Make the editor
	 * 
	 * @return javax.swing.JComponent
	 */
	private JComponent makeEditor(final Controller thisController)
	{
		JSplitPane thisPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
		thisPane.setDividerSize(8);
		thisPane.setOneTouchExpandable(true);
		thisPane.add(theTreeView, JSplitPane.LEFT);
		thisPane.add(makeSubEditor(thisController), JSplitPane.RIGHT);
		return thisPane;
	}

	/**
	 * Make thesubeditor
	 * 
	 * @return javax.swing.JComponent
	 */
	private JComponent makeSubEditor(final Controller thisController)
	{
		JPanel thisPanel = new JPanel();
		thisPanel.setLayout(new BorderLayout());
		thisPanel.add(thePropertyView, BorderLayout.CENTER);
		thisPanel.add(makeDefaultsPanel(thisController), BorderLayout.SOUTH);
		return thisPanel;
	}

	/**
	 * Make the defaults panel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel makeDefaultsPanel(final Controller thisController)
	{
		JPanel thisPanel = new JPanel();
		thisPanel.setLayout(new FlowLayout());
		thisPanel.add(makeGlobalsButton(thisController, Messages.getString("MainFrame.51"), "top.png", Controller.Code.SELECTTOP)); //$NON-NLS-1$ //$NON-NLS-2$
		thisPanel.add(makeGlobalsButton(thisController, Messages.getString("MainFrame.52"), "tree.png", Controller.Code.SELECTTREE)); //$NON-NLS-1$ //$NON-NLS-2$
		thisPanel.add(makeGlobalsButton(thisController, Messages.getString("MainFrame.53"), "nodes.png", Controller.Code.SELECTNODES)); //$NON-NLS-1$ //$NON-NLS-2$
		thisPanel.add(makeGlobalsButton(thisController, Messages.getString("MainFrame.54"), "edges.png", Controller.Code.SELECTEDGES)); //$NON-NLS-1$ //$NON-NLS-2$
		return thisPanel;
	}

	/**
	 * Make the globals theButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton makeGlobalsButton(final Controller thisController, String thisLabel, String thisImage, final Controller.Code thisCode)
	{
		JButton thisButton = new JButton();
		thisButton.setIcon(new ImageIcon(getClass().getResource("images/" + thisImage))); //$NON-NLS-1$
		thisButton.setToolTipText(thisLabel);
		thisButton.setBorder(null);
		thisButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		thisButton.addActionListener(new java.awt.event.ActionListener()
		{
			public void actionPerformed(java.awt.event.ActionEvent e)
			{
				thisController.execute(thisCode, 0);
			}
		});
		return thisButton;
	}
}
